package org.store.service;

import org.store.dao.CategoryDao;
import org.store.dao.DaoException;
import org.store.dao.ProductDao;
import org.store.domain.CategorizedProduct;
import org.store.domain.Category;
import org.store.domain.Product;

import java.util.ArrayList;
import java.util.List;

public class ProductService {
    private ProductDao productDao;
    private CategoryDao categoryDao;
    private CategoriesHolder categoriesHolder;

    public Product getProductById(long id) throws ApplicationException {
        try {
            return productDao.getById(id);
        } catch (DaoException e) {
            throw new SystemException(e);
        }
    }

    public List<Product> getProductByTitle(String title) throws ApplicationException {
        try {
            return productDao.getByTitle(title);
        } catch (DaoException e) {
            throw new SystemException(e);
        }
    }

    public List<Product> getProductsByCategoryId(long categoryId) throws ApplicationException {
        try {
            List<Product> products = new ArrayList<>();
            List<Category> subcategories = categoriesHolder.getSubCategories(categoryId);
            List<Long> categoriesIds = new ArrayList<>();
            for (Category category : subcategories) {
                categoriesIds.add(category.getId());
            }
            if (categoriesIds.isEmpty()) {
                return products;
            }
            products.addAll(productDao.getByCategoryIds(categoriesIds));
            return products;
        } catch (DaoException e) {
            throw new SystemException(e);
        }
    }

    public void saveProduct(Product product) throws ApplicationException {
        try {
            productDao.saveOrUpdate(product);
        } catch (DaoException e) {
            throw new SystemException(e);
        }
    }

    public void saveProducts(List<Product> products) throws ApplicationException {
        try {
            productDao.saveAll(products);
        } catch (DaoException e) {
            throw new SystemException(e);
        }
    }

    public void delete(Product product) throws ApplicationException {
        try {
            if (!productDao.delete(product)) {
                throw new NotFoundException(product);
            }
        } catch (DaoException e) {
            throw new SystemException(e);
        }
    }

    public List<Product> getAll(Integer start, Integer limit) throws ApplicationException {
        try {
            return productDao.getAll(start, limit);
        } catch (DaoException e) {
            throw new SystemException(e);
        }
    }

    public void setProductDao(ProductDao productDao) {
        this.productDao = productDao;
    }

    private CategorizedProduct convert(Product product) throws DaoException {
        return new CategorizedProduct(categoriesHolder.getCategory(product), product);
    }
}
